package org.activityinfo.ui.client.page.entry.form; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.extjs.gxt.ui.client.Style.LayoutRegion; import com.extjs.gxt.ui.client.event.*; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.MessageBox; import com.extjs.gxt.ui.client.widget.Window; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.layout.BorderLayout; import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData; import com.extjs.gxt.ui.client.widget.layout.CardLayout; import com.extjs.gxt.ui.client.widget.layout.FlowLayout; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.Label; import org.activityinfo.core.client.ResourceLocator; import org.activityinfo.i18n.shared.I18N; import org.activityinfo.legacy.client.Dispatcher; import org.activityinfo.legacy.client.callback.SuccessCallback; import org.activityinfo.legacy.shared.adapter.ResourceLocatorAdaptor; import org.activityinfo.legacy.shared.command.CreateSite; import org.activityinfo.legacy.shared.command.UpdateEntity; import org.activityinfo.legacy.shared.command.UpdateSite; import org.activityinfo.legacy.shared.command.exception.NotAuthorizedException; import org.activityinfo.legacy.shared.command.result.CreateResult; import org.activityinfo.legacy.shared.command.result.VoidResult; import org.activityinfo.legacy.shared.model.ActivityFormDTO; import org.activityinfo.legacy.shared.model.LocationDTO; import org.activityinfo.legacy.shared.model.SiteDTO; import org.activityinfo.model.form.FormInstance; import org.activityinfo.model.legacy.KeyGenerator; import org.activityinfo.ui.client.EventBus; import org.activityinfo.ui.client.page.config.design.dialog.NewFormDialog; import org.activityinfo.ui.client.page.entry.form.resources.SiteFormResources; import org.activityinfo.ui.client.style.legacy.icon.IconImageBundle; import java.util.List; import java.util.Map; public class SiteDialog extends Window { private static final int HEIGHT = 470; private static final int WIDTH = 500; private final FormNavigationListView navigationListView; private final LayoutContainer sectionContainer; private final List<FormSection<SiteDTO>> sections = Lists.newArrayList(); private LocationFormSection locationForm; private final Button finishButton; private final Dispatcher dispatcher; private final ResourceLocator resourceLocator; private final ActivityFormDTO activity; private final EventBus eventBus; private SiteDialogCallback callback; private SiteDTO site = null; /** * True if this is a brand new site */ private boolean newSite; private KeyGenerator keyGenerator; public SiteDialog(Dispatcher dispatcher, ActivityFormDTO activity, EventBus eventBus) { this.dispatcher = dispatcher; this.resourceLocator = new ResourceLocatorAdaptor(dispatcher); this.activity = activity; this.eventBus = eventBus; setHeadingText(I18N.MESSAGES.addNewSiteForActivity(activity.getName())); setWidth(WIDTH); setHeight(HEIGHT); setLayout(new BorderLayout()); // show alert only for report frequency ONCE if (activity.getReportingFrequency() == ActivityFormDTO.REPORT_ONCE) { BorderLayoutData alertLayout = new BorderLayoutData(LayoutRegion.NORTH); alertLayout.setSize(30); add(modernViewAlert(), alertLayout); } navigationListView = new FormNavigationListView(); BorderLayoutData navigationLayout = new BorderLayoutData(LayoutRegion.WEST); navigationLayout.setSize(150); add(navigationListView, navigationLayout); sectionContainer = new LayoutContainer(); final CardLayout sectionLayout = new CardLayout(); sectionContainer.setLayout(sectionLayout); add(sectionContainer, new BorderLayoutData(LayoutRegion.CENTER)); if (activity.getLocationType().isAdminLevel()) { locationForm = new BoundLocationSection(dispatcher, activity); } else if (activity.getLocationType().isNationwide()) { locationForm = new NullLocationFormSection(activity.getLocationType()); } else { locationForm = new LocationSection(dispatcher, activity); } addSection(FormSectionModel.forComponent(new ActivitySection(activity)) .withHeader(I18N.CONSTANTS.siteDialogIntervention()) .withDescription(I18N.CONSTANTS.siteDialogInterventionDesc())); if (!activity.getLocationType().isNationwide()) { addSection(FormSectionModel.forComponent(locationForm) .withHeader(I18N.CONSTANTS.location()) .withDescription(I18N.CONSTANTS.siteDialogSiteDesc())); } if (!activity.getAttributeGroups().isEmpty()) { addSection(FormSectionModel.forComponent(new AttributeSection(activity)) .withHeader(I18N.CONSTANTS.attributes()) .withDescription(I18N.CONSTANTS.siteDialogAttributes())); } if (activity.getReportingFrequency() == ActivityFormDTO.REPORT_ONCE && !activity.getIndicators().isEmpty()) { addSection(FormSectionModel.forComponent(new IndicatorSection(activity)) .withHeader(I18N.CONSTANTS.indicators()) .withDescription(I18N.CONSTANTS.siteDialogIndicators())); } addSection(FormSectionModel.forComponent(new CommentSection(315, 330)) .withHeader(I18N.CONSTANTS.comments()) .withDescription(I18N.CONSTANTS.siteDialogComments())); SiteFormResources.INSTANCE.style().ensureInjected(); navigationListView.getSelectionModel() .addSelectionChangedListener(new SelectionChangedListener<FormSectionModel>() { @Override public void selectionChanged(SelectionChangedEvent<FormSectionModel> se) { if (!se.getSelection().isEmpty()) { sectionLayout.setActiveItem(se.getSelectedItem().getComponent()); } } }); finishButton = new Button(I18N.CONSTANTS.save(), IconImageBundle.ICONS.save(), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { finishButton.disable(); if (validateSections()) { saveLocation(); } else { finishButton.enable(); } } }); getButtonBar().add(finishButton); } private LayoutContainer modernViewAlert() { Anchor linkToDesign = new Anchor(I18N.CONSTANTS.switchToNewLayout()); linkToDesign.setHref("#"); linkToDesign.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if (activity.isDesignAllowed()) { Map<String, Object> changes = Maps.newHashMap(); changes.put("classicView", Boolean.FALSE); dispatcher.execute(new UpdateEntity(activity, changes)).then(new SuccessCallback<VoidResult>() { @Override public void onSuccess(VoidResult result) { SiteDialog.this.hide(); resourceLocator.getFormInstance(site.getInstanceId()).then(new SuccessCallback<FormInstance>() { @Override public void onSuccess(FormInstance result) { SiteDialogLauncher.showModernFormDialog(activity.getName(), result, callback, newSite, resourceLocator); } }); } }); } else { MessageBox.alert(I18N.CONSTANTS.alert(), I18N.CONSTANTS.noDesignPrivileges(), new SelectionListener<MessageBoxEvent>() { @Override public void componentSelected(MessageBoxEvent ce) { } }); } } }); Anchor linkToMore = new Anchor(I18N.CONSTANTS.learnMore()); linkToMore.setHref(NewFormDialog.CLASSIC_VIEW_EXPLANATION_URL); linkToMore.setTarget("_blank"); ContentPanel panel = new ContentPanel(); panel.setHeaderVisible(false); panel.setLayout(new FlowLayout()); panel.add(new Label(I18N.CONSTANTS.alertAboutModerView())); panel.add(linkToDesign); panel.add(new InlineLabel(I18N.CONSTANTS.orWithSpaces())); panel.add(linkToMore); return panel; } public void showNew(SiteDTO site, LocationDTO location, boolean locationIsNew, SiteDialogCallback callback) { this.newSite = true; this.callback = callback; locationForm.updateForm(location, locationIsNew); updateForms(site, true); show(); } public void showExisting(SiteDTO site, SiteDialogCallback callback) { this.newSite = false; this.site = site; this.callback = callback; LocationDTO location = site.getLocation(); location.setLocationTypeId(activity.getLocationTypeId()); locationForm.updateForm(location, false); updateForms(site, false); show(); } private void updateForms(SiteDTO site, boolean isNew) { for (FormSectionModel<SiteDTO> section : navigationListView.getStore().getModels()) { section.getSection().updateForm(site, isNew); } } private void updateModel(final SiteDTO newSite) { for (FormSectionModel<SiteDTO> section : navigationListView.getStore().getModels()) { section.getSection().updateModel(newSite); } // no-location: hack locationForm.updateModel(newSite); } private void addSection(FormSectionModel<SiteDTO> model) { navigationListView.addSection(model); sectionContainer.add(model.getComponent()); sections.add(model.getSection()); } private boolean validateSections() { for (FormSectionModel<SiteDTO> section : navigationListView.getStore().getModels()) { if (!section.getSection().validate()) { navigationListView.getSelectionModel().select(section, false); section.getSection().validate(); // validate after render to enable validation-error styling MessageBox.alert(getHeadingHtml(), I18N.CONSTANTS.pleaseCompleteForm(), null); return false; } } return true; } private void saveLocation() { locationForm.save(new AsyncCallback<Void>() { @Override public void onSuccess(Void result) { saveSite(); } @Override public void onFailure(Throwable caught) { showError(caught); } }); } private void saveSite() { if (newSite) { saveNewSite(); } else { updateSite(); } } private void saveNewSite() { final SiteDTO newSite = new SiteDTO(); keyGenerator = new KeyGenerator(); newSite.setId(keyGenerator.generateInt()); newSite.setActivityId(activity.getId()); if (activity.getReportingFrequency() == ActivityFormDTO.REPORT_ONCE) { newSite.setReportingPeriodId(new KeyGenerator().generateInt()); } updateModel(newSite); dispatcher.execute(new CreateSite(newSite), new AsyncCallback<CreateResult>() { @Override public void onFailure(Throwable caught) { showError(caught); } @Override public void onSuccess(CreateResult result) { hide(); callback.onSaved(); } }); } private void updateSite() { final SiteDTO updated = new SiteDTO(site); updateModel(updated); dispatcher.execute(new UpdateSite(site, updated), new AsyncCallback<VoidResult>() { @Override public void onFailure(Throwable caught) { showError(caught); } @Override public void onSuccess(VoidResult result) { hide(); callback.onSaved(); } }); } private void showError(Throwable caught) { finishButton.enable(); if (caught != null && caught instanceof NotAuthorizedException) { MessageBox.alert(I18N.CONSTANTS.dataEntry(), I18N.CONSTANTS.notAuthorized(), null); } else { MessageBox.alert(I18N.CONSTANTS.dataEntry(), I18N.CONSTANTS.serverError(), null); } } }